package com.pan.thread;

import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 多线程下，队列是否会交叉
 */
@Slf4j
public class ThreadPoolDemo2 {

    static ArrayBlockingQueue myblockingQueue = new ArrayBlockingQueue(50);
    //创建一个具有2个核心线程、5个最大线程，使用容量为10的ArrayBlockingQueue阻塞队列作为工作队列的线程池，使用默认的AbortPolicy拒绝策略
    public static ThreadPoolExecutor threadPool = new ThreadPoolExecutor(
            5, 5,
            5, TimeUnit.SECONDS,
            myblockingQueue,
            new ThreadPoolExecutor.AbortPolicy());




    public static void main(String[] args){
        CountDownLatch countDownLatch1 = new CountDownLatch(10);

        List<String> result1 = new ArrayList<>();
        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                ThreadPoolDemo2 threadPoolDemo2 = new ThreadPoolDemo2();
                log.info("thread1:"+ThreadPoolDemo2.threadPool.toString());
                threadPoolDemo2.runTasks(10,result1,"threadPoolDemo1",countDownLatch1,1000);
            }
        });

        CountDownLatch countDownLatch2 = new CountDownLatch(20);
        List<String> result2 = new ArrayList<>();
        Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
                ThreadPoolDemo2 threadPoolDemo2 = new ThreadPoolDemo2();
                log.info("thread2:"+ThreadPoolDemo2.threadPool.toString());
                threadPoolDemo2.runTasks(20,result2,"threadPoolDemo2",countDownLatch2,2000);
            }
        });

        thread1.start();
        thread2.start();

        try {
            countDownLatch2.await();
            countDownLatch1.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        log.info("result1.size():{},result1.toString():{}",result1.size(),result1.toString());
        log.info("result2.size():{},result2.toString():{}",result2.size(),result2.toString());
        threadPool.shutdown();

    }

    public void runTasks(int num,List<String> result,String taskId,CountDownLatch countDownLatch,int sleepTime){

        for (int i = 0; i <num ; i++) {
            threadPool.execute(new Task(result,taskId,countDownLatch,sleepTime));
        }

        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        log.info("result.size():{},result.toString():{}",result.size(),result.toString());
    }



    class Task implements Runnable{

        private List<String> result;

        private String taskId;

        private CountDownLatch countDownLatch;

        private int sleeptime;

        public Task(List<String> result,String taskId,CountDownLatch countDownLatch,int sleeptime){
            this. result = result;
            this.taskId = taskId;
            this.countDownLatch = countDownLatch;
            this.sleeptime =sleeptime;
        }

        @Override
        public void run() {
            try {
                Object peek = myblockingQueue.peek();
                int size = myblockingQueue.size();
                log.info("myblockingQueue.size():{},peek:{}",size,peek);

                Thread.sleep(sleeptime);
                log.info("当前线程是:{}",Thread.currentThread().getName()+taskId);
                result.add(taskId);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }finally {
                countDownLatch.countDown();
            }
        }
    }

}
